<?php


// common/DeviceTcp/PluginManager.php
namespace Common\Plugin\PluginManager;

use Common\Helpers\DebugHelper;
use Common\Plugin\Interface\DevicePluginInterface;

class PluginTcpManager
{
    private array $plugins = [];

    public function register(DevicePluginInterface $plugin): void
    {
        $this->plugins[] = $plugin;
    }

    public function handle($server, int $fd, int $reactorId, string $data): void
    {
        DebugHelper::consoleWrite('插件管理器-handle', [
            'data' => $data,
            'plugins' => $this->plugins,
        ]);
        foreach ($this->plugins as $plugin) {
            if ($plugin->supports($data)) {
                $plugin->handle($server, $fd, $reactorId, $data);
                break;
            }
        }
    }

    /**
     * 获取 TCP 相关的文件列表
     *
     * @param string $directory 目录路径
     * @param array $suffixes 文件后缀过滤
     * @return array
     */
    public function getTcpFiles(string $directory, array $suffixes = ['Tcp.php']): array
    {
        $files = [];
        if (!is_dir($directory)) {
            return $files;
        }

        $dirIterator = new \RecursiveDirectoryIterator($directory);
        $iterator = new \RecursiveIteratorIterator($dirIterator);

        foreach ($iterator as $file) {
            if ($file->isFile()) {
                foreach ($suffixes as $suffix) {
                    if (str_ends_with($file->getFilename(), $suffix)) {
                        $files[] = $file->getPathname();
                        break;
                    }
                }
            }
        }

        return $files;
    }


    public function loadPluginsFromDirectory($directory): void
    {
        $files = $this->getTcpFiles($directory);
        foreach ($files as $file) {
            require_once $file;
            $className = $this->getClassNameFromFile($file);
            if ($className && class_exists($className)) {
                $plugin = new $className();
                if ($plugin instanceof DevicePluginInterface) {
                    $this->register($plugin);
                }
            }
        }
    }

    /**
     * 从文件中提取类名
     *
     * @param string $file 文件路径
     * @return string|null
     */
    private function getClassNameFromFile(string $file): ?string
    {
        $content = file_get_contents($file);
        $tokens = token_get_all($content);
        $namespace = '';
        $className = null;

        foreach ($tokens as $index => $token) {
            if (is_array($token)) {
                if ($token[0] === T_NAMESPACE) {
                    $namespace = '';
                    for ($i = $index + 1; $i < count($tokens); $i++) {
                        if (is_array($tokens[$i]) && $tokens[$i][0] === T_STRING) {
                            $namespace .= $tokens[$i][1] . '\\';
                        } elseif ($tokens[$i] === ';') {
                            break;
                        }
                    }
                } elseif ($token[0] === T_CLASS) {
                    for ($i = $index + 1; $i < count($tokens); $i++) {
                        if (is_array($tokens[$i]) && $tokens[$i][0] === T_STRING) {
                            $className = $namespace . $tokens[$i][1];
                            break 2;
                        }
                    }
                }
            }
        }
        $addons = str_replace('Tcp', '', $className);
        return 'Addons\\' . $addons . '\\' . $className;
    }
}
